<script setup>
import {computed, getCurrentInstance, nextTick, onMounted, ref, watch} from 'vue'
import ButtonX from '@/components/button-x/index.vue'
import Cell from '@/components/cell/index.vue'
import CellItem from '@/components/cell-item/index.vue'
import FooterX from '@/components/footer-x/index.vue'
import {queryNodeRect} from '@/utils/uni-api-wrap/page'
import {isArray, isEmptyArray, isInvalidData} from '@/utils/utils'

const props = defineProps({
  modelValue: {
    type: Array,
    default: () => []
  },
  cancel: Boolean,
  data: {
    type: Array,
    default: () => ([])
  },
  options: {
    type: Object,
    default: () => ({ label: 'label', value: 'value' })
  }
})

const emit = defineEmits(['update:modelValue', 'confirm'])


function getArrayDepth(arr, depth = 1) {
  // 检查数组是否为空
  if (arr.length === 0) {
    return depth
  }

  let maxChildDepth = depth

  // 遍历数组的每个元素
  for (let i = 0; i < arr.length; i++) {
    // 如果元素是数组，则递归调用该函数
    if (Array.isArray(arr[i].children) && arr[i].children.length > 0) {
      const childDepth = getArrayDepth(arr[i].children, depth + 1)
      // 如果子数组的嵌套层级大于当前记录的层级，则更新最大层级
      if (childDepth > maxChildDepth) {
        maxChildDepth = childDepth
      }
    }
  }

  // 返回最大嵌套层级
  return maxChildDepth
}


function _findObj (code, data) {
  for (const item of data) {
    if (item[props.options.value] === code) {
      return item
    }
    if (isArray(item.children)) {
      return _findObj(code, item.children)
    }
  }
  return null
}

const findObjects = (list, data) => {
  const newList = []
  let parentData = data
  for (const code of list) {
    const result = _findObj(code, parentData)
    if (!isInvalidData(result)) {
      newList.push(result)
      parentData = result.children || []
    }
  }
  return newList
}

const instance = getCurrentInstance()

const selectList = ref(findObjects(props.modelValue.map(item => item[props.options.value]), props.data))
const selectIndex = ref(props.modelValue.length - 1 < 0 ? 0 : props.modelValue.length - 1)
const scrollLeft = ref(0)
const popup = ref(null)
const tabber = ref(null)

const arrDepth = computed(() => getArrayDepth(props.data))
const nextList = computed(() => {
  if (selectIndex.value === 0) return props.data
  if (selectIndex.value === arrDepth.value) return selectList.value[selectIndex.value - 2].children || []
  return selectList.value[selectIndex.value - 1].children || []
})
const _selectList = computed(() => {
  if (selectList.value.length < arrDepth.value) {
    return [...selectList.value, { [props.options.label]: '未选择', [props.options.value]: -1 }]
  }
  return [...selectList.value]
})

const change = () => {
}

const open = () => popup.value.open()
const close = () => popup.value.close()

const tabberClick = (index) => {
  selectIndex.value = index
  nextTick(async () => {
    const result = await queryNodeRect(`#tabber-item-${selectIndex.value}`, instance)
    scrollLeft.value = result.left
  })
}

const confirm = () => {
  emit('confirm', selectList.value)
  close()
}

const cellClick = (item) => {
  let list = selectList.value.slice(0, selectIndex.value)
  if (list.length < arrDepth.value) {
    list = [...list, item]
  }
  if (list.length < arrDepth.value) {
    selectIndex.value++
  }
  selectList.value = list
  nextTick(async () => {
    const result = await queryNodeRect(`#tabber-item-${selectIndex.value}`, instance)
    scrollLeft.value = result.right
  })
}

watch(selectList, (newVal) => {
  emit('update:modelValue', newVal)
})

onMounted(() => {
  nextTick(async () => {
    const result = await queryNodeRect(`#tabber-item-${selectIndex.value}`, instance)
    scrollLeft.value = result.right
  })
})

defineExpose({
  open,
  close
})
</script>

<template>
  <uni-popup ref="popup" type="bottom" :safe-area="false" @change="change">
    <view class="data-picker-x-container">
      <view class="data-picker-x-header">
        <view class="data-picker-x-cancel-container" v-if="props.cancel">
          <button-x size="mini">取消</button-x>
        </view>
        <view class="data-picker-x-header-tabber-container">
          <scroll-view scroll-x :scroll-left="scrollLeft">
            <view class="data-picker-x-header-tabber-inner-container">
              <view
                v-for="(item,index) of _selectList"
                :id="`tabber-item-${index}`"
                :key="index"
                class="tabber-item"
                :class="{ 'tabber-item-selected': selectIndex === index }"
                @click="tabberClick(index)"
              >{{ item[props.options.label] }}</view>
            </view>
          </scroll-view>
        </view>
        <view class="data-picker-x-header-operation-container">
          <view class="">
            <button-x size="mini" type="success" @click="confirm">确认</button-x>
          </view>
        </view>
      </view>
      <view class="data-picker-x-context-container">
        <scroll-view scroll-y>
          <footer-x>
            <cell value-dark-color text-align="left">
              <cell-item
                :link="!isInvalidData(item.children)"
                v-for="item of nextList"
                :value="item[props.options.label]"
                :key="item[props.options.value]"
                @click="cellClick(item)"
              />
            </cell>
          </footer-x>
        </scroll-view>
      </view>
    </view>
  </uni-popup>
</template>

<style scoped lang="scss">
.data-picker-x-container {
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  padding: 32rpx;
  height: 65vh;
  border-radius: 32rpx 32rpx 0 0;
  background-color: $kaoyan-color-14;
}
.data-picker-x-header {
  padding-top: 12rpx;
  display: flex;
  flex-direction: row;
  align-items: center;
}
.data-picker-x-header-tabber-container {
  flex: 1;
  width: 100%;
  overflow: hidden;
  .data-picker-x-header-tabber-inner-container {
    display: flex;
    flex-direction: row;
    flex-wrap: nowrap;
    .tabber-item {
      display: inline-block;
      margin-bottom: 10rpx;
      padding: 0 24rpx;
      white-space: nowrap;
      color: $kaoyan-color-9;
      font-size: 20px;
      font-style: normal;
      font-weight: 600;
      line-height: 56rpx;
    }
    .tabber-item-selected {
      position: relative;
      &::after {
        display: block;
        content: '';
        position: absolute;
        bottom: 0;
        left: 50%;
        transform: translate3d(-50%, 100%, 0);
        width: 1.5em;
        height: 8rpx;
        border-radius: 6rpx;
        background-color: $kaoyan-color-7;
      }
    }
  }
}
.data-picker-x-header-operation-container {
  padding-left: 24rpx;
}
.data-picker-x-context-container {
  flex: 1;
  height: 100%;
  scroll-view {
    height: 100%;
  }
}
cell {
  cell-item {
    display: block;
    &:not(:last-child) {
      border-bottom: 2rpx solid $kaoyan-color-12;
    }
  }
}
</style>
